<template>
  <div>
    <!-- 表单的部分 -->
    <div v-loading="updateing">
      <el-form>
        <el-form-item>
          <el-button @click="bucketVisible = true">{{ bucketInfo.info }}</el-button>
        </el-form-item>
        <el-form-item>
          <el-button @click="browseFile">浏览文件...</el-button>
          <span>选择的文件数：{{ files.length }}</span>
        </el-form-item>
        <el-form-item label="文件描述：">
          <el-input v-model="fileinfo" placeholder="文件描述信息"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="danger" @click="reset">
            <el-icon><RefreshLeft /></el-icon>重置
          </el-button>
          <el-button type="primary" :disabled="files.length == 0" @click="upload">
            <el-icon><UploadFilled /></el-icon>上传
          </el-button>
        </el-form-item>
      </el-form>
    </div>
    <!-- 上传进度的部分 -->
    <div v-if="updateing">
      <div v-for="d in uploadInfo" class="progress">
        <el-progress :text-inside="true" :stroke-width="26" :percentage="d.percent" />
      </div>
    </div>
  </div>
  <!-- bucket选择对话框 -->
  <el-dialog v-model="bucketVisible" title="选择bucket">
    <OssBucketComp @bucket-selected="bucketSelected"></OssBucketComp>
  </el-dialog>
</template>
<script setup lang="ts">
//#region 导入

import { ref } from 'vue'
import { ElDialog, ElButton, ElForm, ElFormItem, ElInput, ElMessage } from 'element-plus'
import { OssSignInfo, TbOssBucket, TbOssInfo } from '../ts/types/Oss'
import OssBucketComp from './OssBucketComp.vue'
import { log } from '../ts/logger'
import { FileInfo, UploadInfo } from '../ts/types/FileInfo'
import { OssUploader, OssUploadConfig, UploadOssInfo } from '../ts/OssUploader'
import FileTools from '../ts/FileTools'
import { ApiService } from '../ts/ApiService'
import { BaseDataResult, BaseResult } from '../ts/types/BaseResult'
const emits = defineEmits(['upload-finish'])

//#endregion

//#region 表单
const bucketVisible = ref(false)
const updateing = ref(false)

const bucketInfo = ref({ info: '请选择bucket...' } as TbOssBucket)

const fileinfo = ref('')

const bucketSelected = (info: TbOssBucket) => {
  log.debug('选择的bucket', info)
  bucketInfo.value = info
  bucketVisible.value = false
}

const files = ref<Array<FileInfo>>([])

const browseFile = () => {
  files.value = []
  FileTools.openFile((data: Array<FileInfo>) => {
    files.value = data
    for (let index = 0; index < files.value.length; index++) {
      const file = files.value[index]
      let fi = {} as UploadInfo
      fi.info = '文件名：' + file.name
      fi.percent = 0
      uploadInfo.value.push(fi)
    }
  })
  // 'image/*'
}

const reset = () => {
  fileinfo.value = ''
  files.value = []
  bucketInfo.value = { info: '请选择bucket...' } as TbOssBucket
}
//#endregion

//#region 上传

const uploadInfo = ref([] as Array<UploadInfo>)
const uploadCount = ref(0)

// 上传
const upload = () => {
  updateing.value = true
  // 获取上传的签名信息
  ApiService.get(`/oss/bucket/sign/${bucketInfo.value.obid}`, {}, (data: BaseDataResult<OssSignInfo>) => {
    log.debug('签名信息：', data.data)
    if (!data.success) {
      updateing.value = false
      ElMessage.error(data.message)
      return
    }
    buildUploadInfo(data.data)
  })
}

// 组织上传信息
const buildUploadInfo = (ossSign: OssSignInfo) => {
  uploadCount.value = files.value.length
  // 组织上传信息
  for (let index = 0; index < files.value.length; index++) {
    const fi = files.value[index]
    let indexInfo = index == 0 ? '' : '-' + index
    const objectName = ossSign.objectName + indexInfo + fi.suffix
    let ossuplader = new OssUploader(new OssUploadConfig(), new UploadOssInfo(ossSign.host, objectName, ossSign.policyBase64, ossSign.accessid, ossSign.signature), fi)

    ossuplader.uploader.bind('Init', () => {
      log.debug('upload初始化')
    })

    ossuplader.uploader.bind('FilesAdded', (uploader: plupload.Uploader, file: File) => {
      log.debug('upload添加文件', file, uploader)
    })

    ossuplader.uploader.bind('PostInit', () => {
      log.debug('upload初始化完成')
    })

    ossuplader.uploader.bind('Error', (uploader: plupload.Uploader, err: any) => {
      log.error('upload发生错误：', err, uploader)
      uploadCount.value--
      let ui = uploadInfo.value[index]
      ui.info = '上传' + fi.name + '发生错误'
      ui.success = false
      ui.errorInfo = err
    })

    ossuplader.uploader.bind('BeforeUpload', (uploader: plupload.Uploader, file: File) => {
      log.debug('开始上传:', file, uploader)
      let ui = uploadInfo.value[index]
      ui.info = '开始上传：' + file.name
      ui.percent = 0
    })

    ossuplader.uploader.bind('UploadProgress', (uploader: any, file: any) => {
      let ui = uploadInfo.value[index]
      ui.percent = file.percent
      log.debug('上传:', file, uploader)
    })

    ossuplader.uploader.bind('FileUploaded', (uploader: plupload.Uploader, file: File) => {
      log.debug('上传完成：', file, uploader)
      let ui = uploadInfo.value[index]
      ui.success = true
      ui.percent = 100
      ui.info = file.name + '上传完毕'
    })
    ossuplader.uploader.bind('UploadComplete', () => {
      let ui = uploadInfo.value[index]
      if (ui.success) {
        // 保存到数据库
        let info = {} as TbOssInfo
        info.obid = bucketInfo.value.obid
        info.objectName = ossuplader.ossinfo.key
        info.filename = ossuplader.fileinfo.name
        info.filesize = ossuplader.fileinfo.size
        info.fileinfo = fileinfo.value
        info.contentType = ossuplader.fileinfo.fulltype
        saveOssInfo(info, index)
      }
      if (uploadCount.value <= 0) {
        updateing.value = false
        clearFiles()
      }
    })
    ossuplader.start()
  }
}

// 保存oss文件信息到后端服务
const saveOssInfo = (info: TbOssInfo, index: number) => {
  ApiService.post('/oss/info', info, (data: BaseResult) => {
    log.debug('保存结果', data)
    let ui = uploadInfo.value[index]
    ui.percent = 100
    ui.info = '保存上传文件信息' + info.filename + '完毕'
    uploadCount.value--
    if (uploadCount.value <= 0) {
      updateing.value = false
      clearFiles()
      emits('upload-finish')
      // viewInfo.uploadInfo.push('所有文件上传完毕')
    }
  })
}

// 清除上传的文件
const clearFiles = () => {
  log.debug('清除文件')
  uploadInfo.value.length = 0
  reset()
}

//#endregion
</script>
<style scoped lang="scss">
.progress {
  margin: 0.5rem;
}
</style>
